This document describes a simple file system which can be used to speed up development time, and where the program and data files map into ROM. Application developers need not concern themselves with the format of the file system; an API is provided.
A NitroROM file has the following constituents.
For each block in the file, the developer can specify whether and to what granularity the block should be aligned. If alignment is required, padding will be added.
The ROM header is fixed at the top of the NitroROM file; all other blocks are accessed by direct or indirect pointers relative to the top of the header. Due to this, it is possible for the other blocks to lie in any order in the file.
The following table shows the format of the ROM_Header structure.
| Offset | Size | Type | Name | Use |
|---|---|---|---|---|
| 000h | 8 bytes | u8[] | corp_id | Should be "NINTENDO" *Reserved for system* |
| 008h | 24 bytes | u8[] | reserved_A | Unused, should be 0 |
| 020h | 4 bytes | void* | main_rom_offset | Offset of ARM9 startup code in ROM *Static module params* |
| 024h | 4 bytes | void* | main_entry_address | Entry address [unimplemented] |
| 028h | 4 bytes | void* | main_ram_address | ARM9 destination RAM address |
| 02Ch | 4 bytes | u32 | main_size | Size to copy for ARM9 code |
| 030h | 4 bytes | void* | sub_rom_offset | Offset of ARM7 startup code in ROM |
| 034h | 4 bytes | void* | sub_entry_address | Entry address [unimplemented] |
| 038h | 4 bytes | void* | sub_ram_address | ARM7 destination RAM address |
| 03Ch | 4 bytes | u32 | sub_size | Size to copy for ARM7 code |
| 040h | 4 bytes | ROM_FNTDir* | fnt_offset | Offset of name table in ROM *Nametable params* |
| 044h | 4 bytes | u32 | fnt_size | Size of table |
| 048h | 4 bytes | ROM_FAT* | fat_offset | Offset of allocation table *FAT params* |
| 04Ch | 4 bytes | u32 | fat_size | Table size |
| 050h | 4 bytes | ROM_OVT* | main_ovt_offset | ARM9 overlay offset in ROM *Overlay header params* |
| 054h | 4 bytes | u32 | main_ovt_size | Size of ARM9 overlay |
| 058h | 4 bytes | ROM_OVT* | sub_ovt_offset | ARM7 overlay offset |
| 05Ch | 4 bytes | u32 | sub_ovt_size | Size of ARM7 overlay |
| 060h | 16 bytes | u8[] | reserved_B | Should be 0 *Reserved* |
| 070h | 3984 bytes | u8[] | reserved_C | Again with the 0's |
| 100h | 12288 bytes | u8[] | reserved_D | And again |
This is a supplied binary, linked in with the application ELF. The binary is placed in ROM without modification. The top ROM address for both processors must be aligned at a 512 byte boundary.
This table associates file names with IDs. The table is built up from two sub-tables: a table of directories, and a file table. Directories are distinguished from files by their ID: a file can only have an ID in the range of 0x0000-0xEFFF, and a directory has an ID of 0xF000-0xFFFF. Therefore, there can be a maximum of 61440 files and 4096 directories. Directory sub-table
The size of the directory table implies the number of entries within it; the subscript of a given entry corresponds to a directory ID of subscript+0xF000.
The following table specifies the format of the ROM_FNTDir structure.
| Offset | Size | Type | Name | Use |
|---|---|---|---|---|
| 000h | 4 bytes | u32 | entry_start | Offset of the constituent file sub-table |
| 004h | 2 bytes | u16 | entry_file_id | ID of first file in the file sub-table |
| 006h | 2 bytes | u16 | parent_id | ID of parent directory |
The directory with ID 0xF000 is the root directory. In this case, the parent_id field holds the number of directories contained within the filesystem, since it has no parent. File sub-table
An entry in a file sub-table can be produced with either of two structures; one describes a file entry, and one a directory reference. The developer must choose which structure to use dependent on the circumstances.
The following table describes a ROM_FNTStrFile entry.
| Offset | Size | Type | Name | Use |
|---|---|---|---|---|
| 000h | Bitfield: 1 bit | u8 | entry_type | 0 for a file |
| 000h | Bitfield: 7 bits | u8 | entry_name_length | Length of entry name |
| 001h | [length] bytes | char[] | entry_name | File name (NOT zero terminated) |
This table describes a ROM_FNTStrDir structure.
| Offset | Size | Type | Name | Use |
|---|---|---|---|---|
| 000 | Bitfield: 1 bit | u8 | entry_type | 1 for a dir |
| 000 | Bitfield: 7 bits | u8 | entry_name_length | Length of entry name |
| 001 | [length] bytes | char[] | entry_name | Dir name (NOT zero terminated) |
| [length]+1 | 1 byte | u8 | dir_id_L | Directory sub-table ID, low byte |
| [length]+2 | 1 byte | u8 | dir_id_H | Directory sub-table ID, high byte |
A file or directory name must follow these rules:
Any file entries that are in the same directory are arranged in successive order, and as such get successive IDs. After a directory entry, and after the last file in a directory, a file entry of length 0 and name "\0" is entered.
Example filesystem:
This table is normally created automatically by the compiler and linked in as binary. Since the IDs of the overlay files are not known at compile time, these must be filled in later.
The table comprises an array of ROM_OVT structures, which are described in detail below.
| Offset | Size | Type | Name | Use |
|---|---|---|---|---|
| 000h | 4 bytes | u32 | id | Overlay ID |
| 004h | 4 bytes | void* | ram_address | Point at which to load |
| 008h | 4 bytes | u32 | ram_size | Amount to load |
| 00Ch | 4 bytes | u32 | bss_size | Size of BSS data region |
| 010h | 4 bytes | void* | sinit_init | Static initialiser start address |
| 014h | 4 bytes | void* | sinit_init_end | Static initialiser end address |
| 018h | 4 bytes | u32 | file_id | Overlay file |
| 01Ch | 4 bytes | u32 | reserved | For future expansion |
The FAT is made up of an array of ROM_FAT structures, which are given in detail below. The array subscript corresponds to the file ID given in the FNT. A set of zero values in a FAT entry designates an unused file ID.
| Offset | Size | Type | Name | Use |
|---|---|---|---|---|
| 000h | 4 bytes | void* | top | Start address of file in ROM |
| 004h | 4 bytes | void* | bottom | End address of file in ROM |
The files are simply placed into the NitroROM image at the places specified by the FAT.